package com.weimei.conversionTreasure.http;


import android.util.Base64;
import android.util.Log;


import com.weimei.conversionTreasure.http.entity.BalanceDetailBean;
import com.weimei.conversionTreasure.http.entity.BaseResult;
import com.weimei.conversionTreasure.http.entity.BillBean;
import com.weimei.conversionTreasure.http.entity.ComputerBean;
import com.weimei.conversionTreasure.http.entity.CustomListBean;
import com.weimei.conversionTreasure.http.entity.DealerDetailBean;
import com.weimei.conversionTreasure.http.entity.FaJiaoDetailBean;
import com.weimei.conversionTreasure.http.entity.FaJiaoListBean;
import com.weimei.conversionTreasure.http.entity.FormulaBean;
import com.weimei.conversionTreasure.http.entity.FormulaDetailBean;
import com.weimei.conversionTreasure.http.entity.FormulaListBean;
import com.weimei.conversionTreasure.http.entity.KgjsBean;
import com.weimei.conversionTreasure.http.entity.MonthBean;
import com.weimei.conversionTreasure.http.entity.MonthDetailBean;
import com.weimei.conversionTreasure.http.entity.PaoLiangDetailBean;
import com.weimei.conversionTreasure.http.entity.PaoLiangListBean;
import com.weimei.conversionTreasure.http.entity.SaveListBean;
import com.weimei.conversionTreasure.http.entity.SelKhBean;
import com.weimei.conversionTreasure.http.entity.SheRuBean;
import com.weimei.conversionTreasure.http.entity.UserBean;
import com.weimei.conversionTreasure.http.entity.YMonthDetailBean;
import com.weimei.conversionTreasure.http.entity.YearBean;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.TreeMap;

import io.reactivex.Observable;
import okhttp3.FormBody;
import okhttp3.RequestBody;

/**
 * Created by goldze on 2019/3/26.
 */
public class HttpDataSourceImpl implements HttpDataSource {
    private ApiService apiService;
    private volatile static HttpDataSourceImpl INSTANCE = null;

    public static HttpDataSourceImpl getInstance(ApiService apiService) {
        if (INSTANCE == null) {
            synchronized (HttpDataSourceImpl.class) {
                if (INSTANCE == null) {
                    INSTANCE = new HttpDataSourceImpl(apiService);
                }
            }
        }
        return INSTANCE;
    }

    public static void destroyInstance() {
        INSTANCE = null;
    }

    private HttpDataSourceImpl(ApiService apiService) {
        this.apiService = apiService;
    }


    private String key ="c4560666777kdjkdidcbe5f76d5bc4ff76b###888";
    private Map<String, String> resultMap;
    private MessageDigest alga;

    /**
     * map根据key值比较大小
     */
    private static Map<String, String> sortMapByKey(Map<String, String> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Map<String, String> sortMap = new TreeMap<>(String::compareTo);
        sortMap.putAll(map);
        return sortMap;
    }

    /**
     * 针对微信加密机制的问题，提供一个外部方法来解决
     */
    public void changeDigest() {
        if (alga != null) {
            alga.digest();
        }
    }

    /**
     * 数组转字符串
     *
     * @param b
     * @return
     */
    public static String byte2hex(byte[] b) {
        String hs = "";
        String stmp;
        for (int n = 0; n < b.length; n++) {
            stmp = (Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs;
    }

    /**
     * 内部处理Map集合
     * 得到from表单 (post请求)
     */
    private RequestBody getRequestBody(Map<String, String> map) {
        try {
            alga = MessageDigest.getInstance("SHA-1");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }


        RequestBody requestBody;
        FormBody.Builder builder = new FormBody.Builder();
        map.put("sign", null);
        resultMap = sortMapByKey(map);
        Log.e("LoggingI：", "map:" + resultMap.toString());
        String str = "";
        boolean isFirst = true;

        /**
         * 循环遍历获取key值，拼接sign字符串
         */
        for (Map.Entry<String, String> entry : resultMap.entrySet()) {
            if (entry.getValue() == null) {
                continue;
            }

            if (isFirst) {
                str += entry.getKey() + "=" + Base64.encodeToString(entry.getValue().getBytes(), Base64.DEFAULT).trim();
                isFirst = false;
            } else {
                str = str.trim();
                str += "&" + entry.getKey() + "=" + Base64.encodeToString(entry.getValue().getBytes(), Base64.DEFAULT).trim();
            }
        }
        str = str+"&" + "key" + "=" + key;
//        str = str.replace("+", "%2B");//去除+号
        str = str.replace("\n", "");//去除换行
        str = str.replace("\\s", "");//去除空格
        str = str.replace("&sign=", "");//去除空格
        changeDigest();
        alga.update(str.getBytes());
        Log.e("LoggingI：", "str:" + str);
        /**
         * 循环遍历value值，添加到表单
         */
        for (Map.Entry<String, String> entry : resultMap.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (value == null) {
                value = "";
            }
            if (key.equals("sign")) {
                value = byte2hex(alga.digest());
            } else if (key.equals("key")) {
                continue;
            }
            builder.add(key, value);
            Log.e("LoggingI：", "key:" + key + "--value:" + value);
        }
        requestBody = builder.build();
        return requestBody;
    }


    @Override
    public Observable<BaseResult> userLogin(Map<String, String> map) {
        return apiService.userLogin(getRequestBody(map));
    }

    @Override
    public Observable<UserBean> getUser(Map<String, String> map) {
        return apiService.getUser(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> feedBack(Map<String, String> map) {
        return apiService.feedBack(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> logOff(Map<String, String> map) {
        return apiService.logOff(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> editUser(Map<String, String> map) {
        return apiService.editUser(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addFerment(Map<String, String> map) {
        return apiService.addFerment(getRequestBody(map));
    }

    @Override
    public Observable<FaJiaoDetailBean> fermentDetails(Map<String, String> map) {
        return apiService.fermentDetails(getRequestBody(map));
    }

    @Override
    public Observable<FaJiaoListBean> fermentList(Map<String, String> map) {
        return apiService.fermentList(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addSoakgrain(Map<String, String> map) {
        return apiService.addSoakgrain(getRequestBody(map));
    }

    @Override
    public Observable<PaoLiangListBean> soakgrainList(Map<String, String> map) {
        return apiService.soakgrainList(getRequestBody(map));
    }

    @Override
    public Observable<PaoLiangDetailBean> soakgrainInfo(Map<String, String> map) {
        return apiService.soakgrainInfo(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> delete_soakgrain(Map<String, String> map) {
        return apiService.delete_soakgrain(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> delete_ferment(Map<String, String> map) {
        return apiService.delete_ferment(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> adddealer(Map<String, String> map) {
        return apiService.adddealer(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addcustom(Map<String, String> map) {
        return apiService.addcustom(getRequestBody(map));
    }

    @Override
    public Observable<CustomListBean> customlist(Map<String, String> map) {
        return apiService.customlist(getRequestBody(map));
    }

    @Override
    public Observable<CustomListBean> dealerlist(Map<String, String> map) {
        return apiService.dealerlist(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> delete_custom(Map<String, String> map) {
        return apiService.delete_custom(getRequestBody(map));
    }

    @Override
    public Observable<DealerDetailBean> dealer_details(Map<String, String> map) {
        return apiService.dealer_details(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> delete_balance(Map<String, String> map) {
        return apiService.delete_balance(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> add_balance(Map<String, String> map) {
        return apiService.add_balance(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> edit_balance(Map<String, String> map) {
        return apiService.edit_balance(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> seach_transaction(Map<String, String> map) {
        return apiService.seach_transaction(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> add_transaction(Map<String, String> map) {
        return apiService.add_transaction(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> delete_transaction(Map<String, String> map) {
        return apiService.delete_transaction(getRequestBody(map));
    }

    @Override
    public Observable<SelKhBean> custom_sort(Map<String, String> map) {
        return apiService.custom_sort(getRequestBody(map));
    }

    @Override
    public Observable<SelKhBean> custom_dealer(Map<String, String> map) {
        return apiService.custom_dealer(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addbudget(Map<String, String> map) {
        return apiService.addbudget(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addstorage(Map<String, String> map) {
        return apiService.addstorage(getRequestBody(map));
    }

    @Override
    public Observable<SaveListBean> storagelist(Map<String, String> map) {
        return apiService.storagelist(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> storageinfo(Map<String, String> map) {
        return apiService.storageinfo(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addblanking(Map<String, String> map) {
        return apiService.addblanking(getRequestBody(map));
    }

    @Override
    public Observable<SaveListBean> blankinglist(Map<String, String> map) {
        return apiService.blankinglist(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> blankinginfo(Map<String, String> map) {
        return apiService.blankinginfo(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> deletestorage(Map<String, String> map) {
        return apiService.deletestorage(getRequestBody(map));
    }

    @Override
    public Observable<BillBean> mybill(Map<String, String> map) {
        return apiService.mybill(getRequestBody(map));
    }

    @Override
    public Observable<YMonthDetailBean> month_chart(Map<String, String> map) {
        return apiService.month_chart(getRequestBody(map));
    }

    @Override
    public Observable<YearBean> year_chart(Map<String, String> map) {
        return apiService.year_chart(getRequestBody(map));
    }

    @Override
    public Observable<MonthDetailBean> month_details(Map<String, String> map) {
        return apiService.month_details(getRequestBody(map));
    }

    @Override
    public Observable<MonthBean> monthly_stat(Map<String, String> map) {
        return apiService.monthly_stat(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> editbudget(Map<String, String> map) {
        return apiService.editbudget(getRequestBody(map));
    }

    @Override
    public Observable<BalanceDetailBean> balance_details(Map<String, String> map) {
        return apiService.balance_details(getRequestBody(map));
    }

    @Override
    public Observable<ComputerBean> proofspirit(Map<String, String> map) {
        return apiService.proofspirit(getRequestBody(map));
    }

    @Override
    public Observable<ComputerBean> computedensity(Map<String, String> map) {
        return apiService.computedensity(getRequestBody(map));
    }

    @Override
    public Observable<ComputerBean> getwine(Map<String, String> map) {
        return apiService.getwine(getRequestBody(map));
    }

    @Override
    public Observable<KgjsBean> blending_weight(Map<String, String> map) {
        return apiService.blending_weight(getRequestBody(map));
    }

    @Override
    public Observable<ComputerBean> getvolume(Map<String, String> map) {
        return apiService.getvolume(getRequestBody(map));
    }

    @Override
    public Observable<ComputerBean> computeweight(Map<String, String> map) {
        return apiService.computeweight(getRequestBody(map));
    }

    @Override
    public Observable<SheRuBean> water_addition(Map<String, String> map) {
        return apiService.water_addition(getRequestBody(map));
    }

    @Override
    public Observable<SheRuBean> target_alcohol(Map<String, String> map) {
        return apiService.target_alcohol(getRequestBody(map));
    }

    @Override
    public Observable<SheRuBean> costing(Map<String, String> map) {
        return apiService.costing(getRequestBody(map));
    }

    @Override
    public Observable<SheRuBean> intake_calculation(Map<String, String> map) {
        return apiService.intake_calculation(getRequestBody(map));
    }

    @Override
    public Observable<SheRuBean> degrees(Map<String, String> map) {
        return apiService.degrees(getRequestBody(map));
    }

    @Override
    public Observable<SheRuBean> elevations(Map<String, String> map) {
        return apiService.elevations(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> addformula(Map<String, String> map) {
        return apiService.addformula(getRequestBody(map));
    }

    @Override
    public Observable<FormulaListBean> formulalist(Map<String, String> map) {
        return apiService.formulalist(getRequestBody(map));
    }

    @Override
    public Observable<FormulaDetailBean> formuladetails(Map<String, String> map) {
        return apiService.formuladetails(getRequestBody(map));
    }

    @Override
    public Observable<FormulaBean> recent_formula(Map<String, String> map) {
        return apiService.recent_formula(getRequestBody(map));
    }

    @Override
    public Observable<BaseResult> delete_formula(Map<String, String> map) {
        return apiService.delete_formula(getRequestBody(map));
    }

    @Override
    public Observable<KgjsBean> blending_volume(Map<String, String> map) {
        return apiService.blending_volume(getRequestBody(map));
    }
}
